const xlsx = require('xlsx');

const wb = xlsx.readFile('./data.xlsx');
console.log(wb.SheetNames);

const toRec = ({
    'Date':date, 
    'Price': price, 
    ' Lots ': lots, 
    ' Turnover ':t_o, 
    'O/C': oc,
    ' RealizedP/L ':pl
}) =>
    ({date, price, lots, t_o, oc, pl, ratio: (t_o + pl)/lots})

const toStr = ({ratio, oc}) => 
    `${oc.padEnd(3, '　')} ${ratio.toString().padStart(10)}`

const nearest = (list, given, func=e=>e) => {
    let minDiff = 1E7;
    let index = -1;
    for (let i = 0; i < list.length; i++) {
        const diff = Math.abs(func(list[i]) - func(given));
        if (diff < minDiff) {
            minDiff = diff;
            index = i;
        }
    }

    console.log(index);
    return [index, list[index], minDiff];
}

const padNum = (num, pad=10) => num.toFixed(2).padStart(pad);

const ws = xlsx.utils.sheet_to_json(wb.Sheets['交易记录'])
const recs = ws.map(toRec);

const openStack = [];

for (let i = 1; i < recs.length; i++) {
    if (recs[i].oc === '开') openStack.push(recs[i]);
    if (recs[i].oc === '平今') {
        const [index, open, diff] = nearest(openStack, recs[i], ({ratio}) => ratio);

        if (open === undefined) {
            continue;
        }
        //若价格最近似的开仓记录，手数多于平仓记录，则从本记录中扣除对应手数
        //留待后续扣除，否则清除本开仓记录。若后者平仓记录手数多于开仓，则扣
        //除对应平仓记录中的手数，下次循环仍然扣除本平仓记录，直到扣除完为止

        if (open.lots > recs[i].lots) {
            open.lots -= recs[i].lots;
        } else {
            openStack.splice(index, 1);
            if (open.lots < recs[i].lots) {
                recs[i].lots -= open.lots;
                i--;
            }
        }

        const res = {
            '开仓成交价': padNum(open.price),
            '平仓成交价': padNum(recs[i].price),
            '开仓成交额/手': padNum(open.ratio),
            '平仓成交额/手': padNum(recs[i].ratio)
        }
        console.log(Object.entries(res).map(e => e.join(':')).join(' '))
    }
}
